package com.apes.fn.server.productRequire;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.apes.fn.crm.customerExpand.FnCustomerExpand;
import com.apes.fn.crm.customerExpand.FnCustomerExpandRepository;
import com.apes.scm.masterdata.enumeration.repository.BusinessParamRepository;
import com.apes.fn.misc.file.ImageHandlerService;
import com.apes.fn.server.productRequireManage.model.ParameterTransfer;
import com.apes.fn.server.productRequireManage.model.ReplenishmentBusinessImpAbstract;
import com.apes.framework.api.SpringManager;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.plugin.event.Listener;
import com.apes.framework.plugin.soe.store.database.repository.BusinessAttributeValueRepository;
import com.apes.framework.plugin.soe.store.database.repository.SceneRepository;
import com.apes.framework.util.MapUtil;
import com.apes.pi.service.PiManager;
import com.apes.scm.account.account.service.ProductAccountService;
import com.apes.scm.account.tax.service.TaxService;
import com.apes.scm.contract.model.Contract;
import com.apes.scm.contract.repository.ContractRepository;
import com.apes.scm.masterdata.party.model.PartyRole;
import com.apes.scm.masterdata.party.repository.PartyRoleRepository;
import com.apes.scm.masterdata.product.model.ProductUom;
import com.apes.scm.masterdata.product.repository.ProductUomRepository;
import com.apes.scm.pur.purchaseOrder.model.PurchaseOrder;
import com.apes.scm.pur.purchaseOrder.model.PurchaseOrderItem;
import com.apes.scm.pur.purchaseOrder.repository.PurchaseOrderRepository;
import com.apes.scm.stock.transfer.model.Pick;
import com.apes.scm.stock.transfer.repository.PickRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.persistence.EntityManager;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 类描述：三头六臂订单服务
 *
 * @ClassName SantouPurchaseOrder
 * @Description 描述
 * @Author wushilong
 * @Date 2023/1/2 11:23
 * @Version 1.0
 */
@Service
public class SantouPurchaseOrderService extends ReplenishmentBusinessImpAbstract {
    @Autowired
    private PartyRoleRepository partyRoleRepository;

    @Autowired
    private PiManager piManager;

    @Autowired
    private TaxService taxService;

    @Autowired
    private ProductUomRepository productUomRepository;

    @Autowired
    private ProductRequireRepository productRequireRepository;

    @Autowired
    private PurchaseOrderRepository purchaseOrderRepository;

    @Autowired
    private PickRepository pickRepository;

    @Autowired
    private EntityManager entityManager;

    @Autowired
    private RequireLogisticsRepository requireLogisticsRepository;

    @Autowired
    private ProductRequireItemRepository productRequireItemRepository;

    @Autowired
    private FnCustomerExpandRepository fnCustomerExpandRepository;

    @Autowired
    private ProductAccountService productAccountService;

    /**
     * 创建三头六臂订单
     *
     * @param require 要货单
     */
    public void CreatePurchaseOrder(ProductRequire require) {

        List<ProductRequireItem> requrieItem = require.getProductRequireItems().stream().filter(requireItem -> {
            return StringUtils.hasText(requireItem.getCommodityInquiryOrderId()) && requireItem.getCommodityInquiryOrderId().startsWith("ST") && requireItem.getQtyRequire() - requireItem.getQtyAssigned() > 0;
        }).collect(Collectors.toList());
        if (ObjectUtils.isEmpty(requrieItem) || requrieItem.isEmpty()) return;

        JSONObject data = new JSONObject();
        data.put("require", MapUtil.mapped(require));
        //获取车架号
        FnCustomerExpand fnCustomerExpand = fnCustomerExpandRepository.findOne(require.getCustomerExpand().getId());
        if (fnCustomerExpand != null) {
            data.put("vin", MapUtil.mapped(fnCustomerExpand.getVin()));
        }
        JSONObject result = JSON.parseObject(invoke("sp.santouEnquiry.orderForm", data));
        // 获取三头六臂订单结果
        JSONObject body = result.getJSONObject("body").getJSONObject("result");
        if (Objects.nonNull(body)) {
            require.getProductRequireItems().forEach(item -> {
                if (StringUtils.hasText(item.getCommodityInquiryOrderId()) && item.getCommodityInquiryOrderId().startsWith("ST") && item.getQtyRequire() - item.getQtyAssigned() > 0)
                    //三头六臂只有整单取消，分配数=要货数
                    item.setQtyAssigned(item.getQtyRequire() - item.getQtyEnded());
                //写入库存帐要货制单数量()
                productAccountService.setProductRequireBilling(item.getProduct(), item.getProductRequire().getLocation(), item.getUom(), -1.0*item.getQtyAssigned(), item.getInnerBusinessKey(), item.getId(),
                        item.getProductRequire().getId(), "santou", item.getCompany(), item.getProductRequire().getId());
                productAccountService.setProductPurchasingWay(item.getProduct(), item.getProductRequire().getLocation(), item.getUom(), item.getQtyAssigned(), item.getCompany());
            });
            requireLogistics(body, require);
        }
    }

    /**
     * 记录要货单明细要货跟踪
     *
     * @param result
     * @param require
     */
    private void requireLogistics(JSONObject result, ProductRequire require) {
        RequireLogistics requireLogistics = new RequireLogistics();
        requireLogistics.setOrigin(require.getId());
        requireLogistics.setOriginBusinessType(require.getInnerBusinessType());
        requireLogistics.setMessage("三头六臂采购订单【" + result.getString("id") + "】");
        requireLogisticsRepository.saveAndFlush(requireLogistics);
    }

    /**
     * 要货补货管理向三头六臂发起采购
     *
     * @param request
     * @return
     */
    @Listener(topic = "event:purchase.order.thirdParty")
    public void againLaunch(SimpleRequest request) {
        JSONArray purchaseRequireItems = request.getJO().getJSONArray("item");

//        List<Object> santouList = purchaseRequireItems.stream().filter(item -> {
//            JSONObject param = (JSONObject) item;
//            return param.getString("supplier").contains("006989") && param.getString("purchasingGroup").contains("0241");//测试库：006570/0101 ,正式库：006989/0241
//        }).collect(Collectors.toList());

        if (purchaseRequireItems.size() == 0) return;
        purchaseRequireItems.forEach(item -> {
            JSONObject jsonObject = (JSONObject) item;
            ProductRequire productRequire = productRequireRepository.findOne(jsonObject.getString("productRequireId"));
            CreatePurchaseOrder(productRequire);
            productRequireRepository.save(productRequire);
        });
        productRequireRepository.flush();
    }


    @Override
    public Map sendOrder(JSONObject getJO) {
        JSONArray purchaseRequireItems = getJO.getJSONArray("purchaseRequireItems");

        if (purchaseRequireItems.size() == 0) return new HashMap();
        purchaseRequireItems.forEach(item -> {
            JSONObject jsonObject = (JSONObject) item;
            ProductRequire productRequire = productRequireRepository.findOne(jsonObject.getString("productRequireId"));
            CreatePurchaseOrder(productRequire);
            productRequireRepository.save(productRequire);
        });
        productRequireRepository.flush();
        return new HashMap();
    }

    /**
     * 三头六臂订单发货
     *
     * @param request 请求对象
     */
    private boolean newOrder(SimpleRequest request) {
        //三头六臂回调订单
        JSONObject santouOrder = request.getJO();
        ProductRequire require = productRequireRepository.findOne(santouOrder.getString("relatedNumber"));
        if (Objects.isNull(require)) return false;
        require.setExternalState("shipments");//设置要货单第三方单据状态
        //生成采购订单
        PurchaseOrder purchaseOrder = this.appendPurchaseOrder(require, santouOrder);
        purchaseOrder.setSupplierType("santou");
        List<PurchaseOrderItem> purchaseItems = new ArrayList<>();
        Map carrierInfoCache = new HashMap<>();
        require.getProductRequireItems().stream().filter(requireItem -> !StringUtils.isEmpty(requireItem.getCommodityInquiryOrderId())
                && requireItem.getCommodityInquiryOrderId().startsWith("ST")).forEach(requireItem -> {
            JSONObject spxjdzxbObj = piManager.synErp("scmGysxjdService.queryBaturuoffer", MapUtil.mapper("XJDH", requireItem.getCommodityInquiryOrderId(), "SPID", requireItem.getProduct().getId()));
            JSONObject xjzxbData = spxjdzxbObj.getJSONObject("obj"); // 考虑报错情况
            double requireQty = requireItem.getQtyRequire();

            ParameterTransfer parameterTransfer = new ParameterTransfer(requireItem.getProduct().getId(), requireItem.getCommodityInquiryOrderId(), require.getSource(),
                    requireQty, purchaseOrder.getContract().getSettlementType(), xjzxbData);
            parameterTransfer.setCarrier(carrierInfoCache);

            purchaseItems.add(appendPurchaseOrderItem(purchaseOrder, requireItem, parameterTransfer));
        });

        purchaseOrder.setPurchaseItems(purchaseItems);
        PurchaseOrder purchaseOrder1 = purchaseOrderRepository.save(purchaseOrder);
        Object invoke = invoke("purchase.order.approve", JSON.toJSONString(purchaseOrder1));
        if (invoke == null) return false;
        purchaseOrderRepository.save(purchaseOrder1);
        productRequireRepository.saveAndFlush(require);
        return true;
    }

    /**
     * 生成采购订单
     *
     * @param require 要货单
     * @return
     */
    private PurchaseOrder appendPurchaseOrder(ProductRequire require, JSONObject santouOrder) {
        PurchaseOrder purchaseOrder = new PurchaseOrder();
        String systemEnvironment = SpringManager.getBean(BusinessParamRepository.class).findOne("20").getValue();
        PartyRole supplier = "pro".equals(systemEnvironment) ? partyRoleRepository.findValidSupplier("006989", "006989")
                : partyRoleRepository.findValidSupplier("006570", "006570");
        List<Contract> contracts = SpringManager.getBean(ContractRepository.class).findValidPlatformSupplier(supplier);
        Contract contract = contracts.get(0);
        purchaseOrder.setScene(SpringManager.getBean(SceneRepository.class).findOne("PO001"));
        purchaseOrder.setCreator(require.getApproveId().getId());
        purchaseOrder.setProductRequire(require.getId());
        purchaseOrder.setCreateUid(require.getApproveId());
        purchaseOrder.setState("approve");
        purchaseOrder.setClerk(require.getApproveId());
        purchaseOrder.setContract(contract);
        purchaseOrder.setCooperation(contract.getCooperation());
        purchaseOrder.setLocation(require.getLocation());
        purchaseOrder.setSupplier(supplier);
        purchaseOrder.setMoveType(contract.getMoveType());
        purchaseOrder.setApproveUid(require.getApproveId());
        purchaseOrder.setOrigin(require.getSource());
        purchaseOrder.setOriginBusinessType(require.getSourceBusinessType());
        purchaseOrder.setOriginTypeName(require.getSourceBusinessTypeName());
        purchaseOrder.setCarryType(SpringManager.getBean(BusinessAttributeValueRepository.class).findOne(contract.getCarryType().getId()));
        purchaseOrder.setProductRequire(require.getId());
        purchaseOrder.setSource(require.getId());
        purchaseOrder.setSupplierRef(santouOrder.getString("id"));
        purchaseOrder.setSourceType(require.getInnerBusinessType());
        purchaseOrder.setSourceTypeName(require.getSourceBusinessTypeName());
        purchaseOrder.setPurchasingGroup("pro".equals(systemEnvironment) ? "0241" : "0101");
        purchaseOrder.setCarLicense(require.getCustomerExpand().getCarLicense());
        purchaseOrder.setDept(contract.getDept()); // 是合同的部门
        purchaseOrder.setCompany(contract.getCompany()); // 是合同的公司

        if (!Objects.isNull(require.getCustomerExpand())) {
            purchaseOrder.setCustomerExpandId(require.getCustomerExpand().getId());
            purchaseOrder.setCarLicense(require.getCustomerExpand().getCarLicense());
        }
        return purchaseOrder;
    }

    /**
     * 生成采购订单明细
     *
     * @param purchaseOrder     采购订单
     * @param requireItem       采购订单明细
     * @param parameterTransfer
     * @return
     */
    private PurchaseOrderItem appendPurchaseOrderItem(PurchaseOrder purchaseOrder, ProductRequireItem requireItem, ParameterTransfer parameterTransfer) {
        String systemEnvironment = SpringManager.getBean(BusinessParamRepository.class).findOne("20").getValue();
        PartyRole supplier = "pro".equals(systemEnvironment) ? partyRoleRepository.findValidSupplier("006989", "006989")
                : partyRoleRepository.findValidSupplier("006570", "006570");
        PurchaseOrderItem purchaseItem = new PurchaseOrderItem();
        purchaseItem.setProduct(requireItem.getProduct());
        purchaseItem.setTax(taxService.getPurchaseTax(supplier, requireItem.getProduct()));
        purchaseItem.setPriceUnit(parameterTransfer.getXjzxbData().getDoubleValue("CGDJ"));
        purchaseItem.setSourceState(requireItem.getSourceState());
        purchaseItem.setExpectedArrivalTime(requireItem.getExpectedArrivalTime());  //  ?
        purchaseItem.setSettlementType(parameterTransfer.getSettlementType());
        purchaseItem.setExternalCode(parameterTransfer.getXjzxbData().getString("WYZ"));
        purchaseItem.setPurchaseOrder(purchaseOrder);
        purchaseItem.setSourceItemId(requireItem.getId());
        this.conversionUomQty(requireItem, purchaseItem);
        purchaseItem.computeAmt();
        return purchaseItem;
    }

    // 三头六臂 - 生成采购订单 - 单位换算
    private void conversionUomQty(ProductRequireItem requireItem, PurchaseOrderItem purchaseItem) {
        double requireQty = requireItem.getQtyRequire() - requireItem.getQtyEnded();
        if (requireItem.getUom().isPurchaseFirst()) {
            purchaseItem.setUom(requireItem.getUom());
        } else {
            ProductUom purchaseUom = productUomRepository.findBypurchaseUom(requireItem.getProduct().getId());
            purchaseItem.setUom(purchaseUom);
            requireQty = requireItem.getUom().computeQty(requireQty, purchaseUom, true);
        }
        purchaseItem.setEffectiveQty(requireQty);
        purchaseItem.setProductUomQty(requireQty);
        purchaseItem.setDemandQty(requireQty);
    }

    /**
     * 三头六臂取消订单
     *
     * @return
     */
    public boolean cancelOrder(SimpleRequest request) {
        JSONObject santouOrder = request.getJO();
        ProductRequire productRequire = productRequireRepository.findOne(santouOrder.getString("relatedNumber"));
        if (Objects.isNull(productRequire)) return false;
        productRequire.setExternalState("cancel");//设置要货单第三方单据状态
        productRequire.getProductRequireItems().forEach(item -> {
            //写入库存帐要货制单数量()
            productAccountService.setProductRequireBilling(item.getProduct(), item.getProductRequire().getLocation(), item.getUom(), item.getQtyAssigned(), item.getInnerBusinessKey(), item.getId(),
                    item.getProductRequire().getId(), "santou", item.getCompany(), item.getProductRequire().getId());
            productAccountService.setProductPurchasingWay(item.getProduct(), item.getProductRequire().getLocation(), item.getUom(), -item.getQtyAssigned(), item.getCompany());
            //三头六臂只有整单取消，分配数=0
            item.setQtyAssigned(0);
        });
        productRequireItemRepository.saveAll(productRequire.getProductRequireItems());
        productRequireRepository.saveAndFlush(productRequire);
        return true;
    }

    /**
     * 自动收货
     *
     * @param request {"santouOrder":"", "":""}
     * @return
     */
    public boolean confirmReceipt(SimpleRequest request) {
        JSONObject jo = request.getJO();
        PurchaseOrder purchaseOrder = purchaseOrderRepository.findBysupplierRef(jo.getString("id"));
        Pick pick = pickRepository.findByOrigin(purchaseOrder.getId());
        pick.getPickItems().forEach(pickItem -> {
            pickItem.setQtyDone(pickItem.getOrderedQty());
        });
        //获取三头六臂图片
        String imgUrl = jo.getString("signVoucherURL");
        int index = imgUrl.lastIndexOf("?");

        List signVoucherImg = SpringManager.getBean(ImageHandlerService.class).storeImg(imgUrl, jo.getString("id"),
                jo.getString("relatedNumber"), index);
        pick.setSignVoucher(new JSONArray(signVoucherImg).toJSONString());
        entityManager.detach(pick);
        //调用交货单收货
        List list = sendSynEvent("event:stock.pick.pda", pick);

        if (Objects.isNull(list)) return false;
        return true;
    }
}

